#!/bin/sh

e2e_test_install() {
  NODE_LABEL_KEY="$(random_string)"
  NODE_LABEL_VALUE="$(random_string)"

  DISTRIBUTEDLOGS_NAME="$(get_sgdistributedlogs_name distributedlogs)"
  BACKUP_NAME="$(get_sgbackup_name "$CLUSTER_NAME")"

  kubectl create namespace "$CLUSTER_NAMESPACE"

  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGInstanceProfile
metadata:
  name: size-s
  namespace: $CLUSTER_NAMESPACE
spec:
  cpu: '1'
  memory: '2Gi'
EOF

  deploy_curl_pod "$CLUSTER_NAMESPACE"
}

e2e_test() {
  run_test "Creating a custom annotations directly on the cluster CR" direct_custom_annotations

  run_test "Creating a custom annotations with the helm chart" helm_custom_annotations

  run_test "Creating a custom annotations with http api" create_api_custom_annotations

  run_test "Getting a custom annotations with http api" get_api_custom_annotations
}

direct_custom_annotations(){
  local POD_RANDOM_VALUE="$(random_string)"
  local SERVICE_RANDOM_VALUE="$(random_string)"
  local OTHER_POD_RANDOM_VALUE="$(random_string)"
  local OTHER_SERVICE_RANDOM_VALUE="$(random_string)"
  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: $CLUSTER_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  instances: 1
  postgres:
    version: "$E2E_POSTGRES_VERSION"
  metadata:
    annotations:
      clusterPods:
        test-annotation: '$POD_RANDOM_VALUE'
      services:
        service-annotation: '$SERVICE_RANDOM_VALUE'
  pods:
    persistentVolume:
      size: '128Mi'
    scheduling:
      nodeSelector:
        $NODE_LABEL_KEY: $NODE_LABEL_VALUE
  sgInstanceProfile: 'size-s'
  nonProductionOptions:
    disableClusterPodAntiAffinity: true
EOF

  wait_until check_sts_annotation "$POD_RANDOM_VALUE"

  wait_until check_pod_annotation "0" "$POD_RANDOM_VALUE"

  wait_until check_service_annotation "" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "primary" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "replicas" "$SERVICE_RANDOM_VALUE"

  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: $CLUSTER_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  instances: 1
  postgres:
    version: "$E2E_POSTGRES_VERSION"
  metadata:
    annotations:
      clusterPods:
        test-annotation: '$POD_RANDOM_VALUE'
        other-test-annotation: '$OTHER_POD_RANDOM_VALUE'
      services:
        service-annotation: '$SERVICE_RANDOM_VALUE'
        other-service-annotation: '$OTHER_SERVICE_RANDOM_VALUE'
  pods:
    persistentVolume:
      size: '128Mi'
    scheduling:
      nodeSelector:
        $NODE_LABEL_KEY: $NODE_LABEL_VALUE
  sgInstanceProfile: 'size-s'
  nonProductionOptions:
    disableClusterPodAntiAffinity: true
EOF

  POD_ANNOTATION=other-test-annotation \
    wait_until check_sts_annotation "$OTHER_POD_RANDOM_VALUE"

  POD_ANNOTATION=other-test-annotation \
    wait_until check_pod_annotation "0" "$OTHER_POD_RANDOM_VALUE"

  SERVICE_ANNOTATION=other-service-annotation \
    wait_until check_service_annotation "" "$OTHER_SERVICE_RANDOM_VALUE"
  SERVICE_ANNOTATION=other-service-annotation \
    wait_until check_service_annotation "primary" "$OTHER_SERVICE_RANDOM_VALUE"
  SERVICE_ANNOTATION=other-service-annotation \
    wait_until check_service_annotation "replicas" "$OTHER_SERVICE_RANDOM_VALUE"

  kubectl delete sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME"
}

helm_custom_annotations(){
  local POD_RANDOM_VALUE="$(random_string)"
  local SERVICE_RANDOM_VALUE="$(random_string)"

  kubectl create secret generic -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME-minio" \
     --from-literal=accesskey=test --from-literal=secretkey=test

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" 2 \
    --set "cluster.pods.scheduling.nodeSelector.$NODE_LABEL_KEY=$NODE_LABEL_VALUE" \
    --set cluster.metadata.annotations.clusterPods.test-annotation="$POD_RANDOM_VALUE" \
    --set cluster.metadata.annotations.services.service-annotation="$SERVICE_RANDOM_VALUE" \
    --set distributedLogs.enabled=true \
    --set cluster.distributedLogs.sgDistributedLogs="$DISTRIBUTEDLOGS_NAME" \
    --set distributedLogs.metadata.annotations.clusterPods.test-annotation="$POD_RANDOM_VALUE" \
    --set distributedLogs.metadata.annotations.services.service-annotation="$SERVICE_RANDOM_VALUE"

  wait_until check_sts_annotation "$POD_RANDOM_VALUE"

  wait_until check_service_annotation "" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "primary" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "replicas" "$SERVICE_RANDOM_VALUE"

  (
  CLUSTER_NAME="$DISTRIBUTEDLOGS_NAME"
  wait_until check_sts_annotation "$POD_RANDOM_VALUE"

  wait_until check_service_annotation "" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "primary" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "replicas" "$SERVICE_RANDOM_VALUE"
  )

  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGBackup
metadata:
  name: $BACKUP_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
EOF

  kubectl delete sgbackup -n "$CLUSTER_NAMESPACE" "$BACKUP_NAME"

  helm uninstall "$CLUSTER_NAME" --namespace "$CLUSTER_NAMESPACE"
}

get_cluster_json() {
  POD_ANNOTATION_VALUE="$1"
  SERVICE_ANNOTATION_VALUE="$2"

  CLUSTER_JSON="$(kubectl get sgclusters.stackgres.io -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" -o json \
    | jq 'del(.metadata.creationTimestamp) | del(.metadata.generation)' \
    | jq 'del(.metadata.resourceVersion) | del(.metadata.selfLink) | del(.metadata.uid)' \
    | jq 'del(.apiVersion) | del(.kind)' \
    | jq ".spec.metadata.annotations.clusterPods[\"test-annotation\"]=\"$POD_ANNOTATION_VALUE\"" \
    | jq ".spec.metadata.annotations.services[\"service-annotation\"]=\"$SERVICE_ANNOTATION_VALUE\"" )"
  echo "$CLUSTER_JSON"
}

assert_http_status_succcess(){
  HTTP_STATUS="$1"
  if [ "$HTTP_STATUS" = "200" ] || [ "$HTTP_STATUS" = "202" ] || [ "$HTTP_STATUS" = "204" ]
  then
    success "Successful request"
  else
    fail "Request not successful"
  fi
}

create_cluster_with_api(){
  HTTP_STATUS="$(run_curl -r "stackgres/sgclusters" -d "$LOG_PATH/stackgres-cluster.json" -e '-X POST -w %{http_code} -o /dev/null')"
  assert_http_status_succcess "$HTTP_STATUS"
}

create_api_custom_annotations(){
  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: $CLUSTER_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  instances: 2
  postgres:
    version: "$E2E_POSTGRES_VERSION"
  pods:
    persistentVolume:
      size: '128Mi'
    scheduling:
      nodeSelector:
        $NODE_LABEL_KEY: $NODE_LABEL_VALUE
  sgInstanceProfile: 'size-s'
  nonProductionOptions:
    disableClusterPodAntiAffinity: true
EOF

  local POD_RANDOM_VALUE="$(random_string)"
  local SERVICE_RANDOM_VALUE="$(random_string)"

  CLUSTER_JSON="$(get_cluster_json "$POD_RANDOM_VALUE" "$SERVICE_RANDOM_VALUE")"

  echo_raw "$CLUSTER_JSON" > "$LOG_PATH/stackgres-cluster.json"

  kubectl delete sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME"

  create_cluster_with_api

  wait_until check_sts_annotation "$POD_RANDOM_VALUE"

  wait_until check_service_annotation "" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "primary" "$SERVICE_RANDOM_VALUE"
  wait_until check_service_annotation "replicas" "$SERVICE_RANDOM_VALUE"

  kubectl delete sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME"
}

get_api_custom_annotations() {
  local POD_RANDOM_VALUE="$(random_string)"
  local SERVICE_RANDOM_VALUE="$(random_string)"

  cat <<EOF | kubectl apply -f -
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: $CLUSTER_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  instances: 2
  postgres:
    version: "$E2E_POSTGRES_VERSION"
  metadata:
    annotations:
      clusterPods:
        test-annotation: '$POD_RANDOM_VALUE'
      services:
        service-annotation: '$SERVICE_RANDOM_VALUE'
  pods:
    persistentVolume:
      size: '128Mi'
    scheduling:
      nodeSelector:
        $NODE_LABEL_KEY: $NODE_LABEL_VALUE
  sgInstanceProfile: 'size-s'
  nonProductionOptions:
    disableClusterPodAntiAffinity: true
EOF
  local POD_ANNOTATION_VALUE
  POD_ANNOTATION_VALUE="$(run_curl -r "stackgres/namespaces/$CLUSTER_NAMESPACE/sgclusters/$CLUSTER_NAME" | jq '.spec.metadata.annotations.clusterPods["test-annotation"]' -r)"
  local SERVICE_ANNOTATION_VALUE
  SERVICE_ANNOTATION_VALUE="$(run_curl -r "stackgres/namespaces/$CLUSTER_NAMESPACE/sgclusters/$CLUSTER_NAME" | jq '.spec.metadata.annotations.services["service-annotation"]' -r)"

  assert_string_equal "$POD_RANDOM_VALUE" "$POD_ANNOTATION_VALUE"
  assert_string_equal "$SERVICE_RANDOM_VALUE" "$SERVICE_ANNOTATION_VALUE"
}
